/*
 * event.c
 *
 *  Created on: 2013. 10. 16.
 *      Author: jphong
 */

#include "np.h"
#include "packet.h"

extern struct timeval *timer;
/* get an event
 * 		TIMEOUT: timer expired
 * 		RDT_RCV: receiver's feedback arrived
 * 		RDT_SEND: application requests to send data
 * */
Event getEvent(int fd, int sockfd) {
	struct timeval now, interval, *tvp;
	fd_set rset;
	int maxp1, rc;

	if (timer != NULL ) {			// if timer is running
		if (gettimeofday(&now, NULL ) < 0)
			error(1, errno, "gettimeofday failure");
		if (!timercmp(&now, timer, <)) {	// timeout elapsed
			timer = NULL;					// Reset timer
			return TIMEOUT;
		} else {
			timersub(timer, &now, &interval);
		}
		tvp = &interval;		// get the time difference for timeout
	} else
		tvp = NULL;			// no timer

	FD_ZERO(&rset);
	FD_SET(fd, &rset);
	FD_SET(sockfd, &rset);
	maxp1 = ((fd < sockfd) ? sockfd : fd) + 1;
	rc = select(maxp1, &rset, NULL, NULL, tvp); // Wait for data from above, packet from udt, or timeout
	if (rc < 0)
		error(1, errno, "select error");
	if (rc == 0) {					// timeout event
		timer = NULL;					// Reset timer
		return TIMEOUT;
	}
	if (FD_ISSET(sockfd, &rset)) 	// feed-back arrived
		return RDT_RCV;
	if (FD_ISSET(fd, &rset)) 		// app data ready
		return RDT_SEND;

	return -1;						// Never happen!
}

